import { isRef, onUnmounted, Ref, ref, unref, watch } from 'vue';
import type {
  VxeGridInstance,
  VxeGridProps,
  VxeGridMethods as OriginalVxeGridMethods,
  VxeFormMethods as OriginalVxeFormMethods,
} from 'vxe-table';
import { ElMessage } from 'element-plus';
import { VxeFormInstance } from 'vxe-pc-ui/types/components/form';
import { VxeTableInstance, VxeTablePropTypes } from 'vxe-pc-ui/types/components/table';

/**
 * 分页信息接口
 */
export interface PageInfo {
  /** 当前页码 */
  currentPage: number;
  /** 每页条数 */
  pageSize: number;
  /** 总条数 */
  total?: number;
}

/**
 * Grid表格引用实例接口
 * 扩展了VxeGridInstance，保持原有的类型声明
 */
export interface GridRefInstance extends VxeGridInstance {
  /** 获取表格引用 */
  getGridRef: () => GridRefInstance;
  /** 设置表格属性 */
  setProps: (props: VxeGridProps) => void;
  /** 获取表格指定属性 */
  getPropField: (prop: string) => any;
  /** 设置表格指定属性 */
  setPropField: (prop: string, value: any) => void;
  /** 获取表格属性 */
  getProps: (prop: string) => any;
}

/**
 * 扩展的Grid方法接口
 * 仅包含我们新增的方法，不覆盖原有方法
 */
export interface ExtendedGridMethods<T = any> {
  /** 获取表格引用 */
  getGridRef: () => Ref<GridRefInstance | undefined>;
  /** 获取表格数据 */
  getTableData: () => T[] | undefined;
  /** 获取表单数据 */
  getFormData: () => Record<string, any>;
  /** 获取分页信息 */
  getPageInfo: () => PageInfo;
  /** 重置表单 */
  resetForm: () => void;
  /** 重置所有状态 */
  reset: () => void;
  /** 查询数据 */
  queryData: () => void;
  /** 获取当前页数据 */
  getCurrentPageData: () => T[] | undefined;
}

/**
 * 合并后的VxeGrid方法类型
 * 包含原有的VxeGridMethods和我们扩展的方法
 */
export type VxeGridMethods<T = any> = OriginalVxeGridMethods &
  OriginalVxeFormMethods &
  ExtendedGridMethods<T>;

/**
 * VxeGrid 组件的 Hook
 * @param gridOptions - 表格配置项
 * @returns 表格相关的方法和属性
 */
export function useVxeGrid<T>(gridOptions?: Ref<VxeGridProps<T>> | VxeGridProps<T>) {
  const gridRef = ref<GridRefInstance>();
  const propsRef = ref<VxeGridProps<T> | undefined>({});

  /**
   * 获取分页信息
   * @returns 分页信息对象
   */
  function getPageInfo(): PageInfo {
    const grid = unref(gridRef);
    return grid?.getProxyInfo()?.pager as PageInfo;
  }

  /**
   * 获取表单数据
   * @returns 表单数据对象
   */
  function getFormData(): Record<string, any> {
    const grid = unref(gridRef);
    if (!grid) return {};
    return grid.getProxyInfo()?.form || {};
  }

  /**
   * 获取表单实例
   * @returns 表单实例
   */
  function getRefForm(): VxeFormInstance | null {
    const grid = unref(gridRef);
    if (!grid) return null;
    return unref(grid.getRefMaps().refForm);
  }

  /**
   * 获取表格实例
   * @returns 表格实例
   */
  function getRefTable() {
    const grid = unref(gridRef);
    if (!grid) return;
    return unref(grid.getRefMaps().refTable) as VxeTableInstance<any>;
  }

  /**
   * 查询数据
   */
  function queryData() {
    const grid = unref(gridRef);
    if (!grid) return;
    // 重置分页到第一页并清空查询条件
    grid.commitProxy('query');
  }

  /**
   * 重置表单
   */
  function resetForm() {
    const grid = unref(gridRef);
    if (!grid) return;
    getRefForm()?.reset();
    // 重置分页到第一页并清空查询条件
    grid.commitProxy('query');
  }

  /**
   * 重置所有状态
   */
  function reset() {
    const grid = unref(gridRef);
    if (!grid) return;

    // 清除选中状态
    grid.clearCheckboxRow();
    // 重置排序
    grid.clearSort();
    // 重置筛选
    grid.clearFilter();
    // 重置表单
    resetForm();
  }

  /**
   * 注册表格实例
   * @param instance - 表格实例
   * @param callback
   */
  function register(instance: GridRefInstance, callback: (props: any) => void) {
    onUnmounted(() => {
      gridRef.value = undefined;
      propsRef.value = undefined;
    });
    if (gridRef.value && instance) return;
    gridRef.value = instance;
    watch(
      () => gridOptions,
      (props) => {
        propsRef.value = isRef(props) ? props.value : props;
        unref(gridRef)?.setProps(propsRef.value as VxeGridProps);
      },
      {
        immediate: true,
        deep: true,
      },
    );

    callback(unref(propsRef));
  }

  // 获取表格实例
  function getGridRef() {
    return gridRef;
  }

  // 获取表格数据
  function getTableData() {
    return getRefTable()?.reactData.tableData;
  }

  /**
   * 获取选中行数据
   * @returns 选中的行数据数组
   */
  function getCheckboxRecords<T = any>(): T[] {
    const grid = unref(gridRef);
    if (!grid) return [];
    return grid.getCheckboxRecords() || [];
  }

  // 设置选中行
  function setCheckboxRow(rows: any[]) {
    if (!unref(gridRef)) return;
    return getRefTable()?.setCheckboxRow(rows, true);
  }

  // 清除选中行
  function clearCheckboxRow() {
    if (!unref(gridRef)) return;
    return getRefTable()?.clearCheckboxRow();
  }

  // 获取当前页数据
  function getCurrentPageData() {
    if (!unref(gridRef)) return;
    return getRefTable()?.reactData?.tableData;
  }

  /**
   * 导出数据
   * @param options - 导出配置
   */
  async function exportData(options?: VxeTablePropTypes.ExportConfig) {
    const grid = unref(gridRef);
    if (!grid) return;

    try {
      await grid.exportData({
        type: 'xlsx', // 导出类型 csv xlsx txt pdf html
        mode: 'current', //导出模式 all current checked
        ...options,
      });
    } catch (error) {
      console.error('导出失败:', error);
      ElMessage.error('导出失败');
    }
  }

  /**
   * 导入数据
   * @param options - 导入配置
   */
  async function importData(options?: VxeTablePropTypes.ImportConfig) {
    const grid = unref(gridRef);
    if (!grid) return;
    await grid.importData(options);
  }

  // commitProxy
  function commitProxy(type: string) {
    const grid = unref(gridRef);
    if (!grid) return;
    grid.commitProxy(type);
  }

  // 打印数据
  function print(options?: VxeTablePropTypes.PrintConfig) {
    if (!unref(gridRef)) return;
    return getRefTable()?.print(options);
  }

  // 手动校验
  function validate() {
    if (!unref(gridRef)) return;
    return getRefForm()?.validate();
  }

  // 清除校验
  function clearValidate() {
    if (!unref(gridRef)) return;
    return getRefForm()?.clearValidate();
  }

  // 扩展的Grid方法，这些是我们自己添加的方法，不属于原生VxeGrid
  const extendedGridMethods: ExtendedGridMethods<T> = {
    getGridRef,
    getTableData,
    getFormData,
    getPageInfo,
    resetForm,
    reset,
    queryData,
    getCurrentPageData,
  };

  // 创建动态代理方法
  // 这个函数会创建一个代理方法，当方法被调用时，会尝试从gridRef或相应实例中获取对应的方法
  function createMethodProxy(methodName: string) {
    return (...args: any[]) => {
      const grid = unref(gridRef);
      if (!grid) return;

      // 优先从Grid实例获取方法
      if (typeof grid[methodName as keyof GridRefInstance] === 'function') {
        return (grid as any)[methodName](...args);
      }

      // 其次从Table实例获取方法
      const table = getRefTable();
      if (table && typeof table[methodName as keyof VxeTableInstance<any>] === 'function') {
        return (table as any)[methodName](...args);
      }

      // 最后从Form实例获取方法
      const form = getRefForm();
      if (form && typeof form[methodName as keyof VxeFormInstance] === 'function') {
        return (form as any)[methodName](...args);
      }
    };
  }

  // VxeGridMethods 所有方法名列表
  // 从VxeGridMethods提取所有方法名
  const vxeGridMethodNames = [
    // 数据操作方法
    'loadData',
    'reloadData',
    'loadColumn',
    'reloadColumn',
    'getTableData',
    'getFormData',
    'submitForm',
    'reset',
    'validate',
    'validateField',
    'clearValidate',
    'updateItems',
    'getItems',
    'getItemByField',
    'collapseAll',
    'expandAll',
    'resetForm',
    'insert',
    'insertAt',
    'remove',
    'removeSelecteds',
    'getRecordset',
    'getRowById',
    'getRowIndex',
    'getColumns',
    'getColumnById',
    'getColumnByField',
    'getColumnIndex',

    // 选择相关方法
    'getRadioRecord',
    'getCheckboxRecords',
    'getCurrentRecord',
    'getCurrentColumn',
    'setRadioRow',
    'setCheckboxRow',
    'setCurrentRow',
    'setCurrentColumn',
    'clearCurrentRow',
    'clearCurrentColumn',
    'clearRadioRow',
    'clearCheckboxRow',

    // 展开相关方法
    'getRowExpandRecords',
    'getTreeExpandRecords',
    'toggleRowExpand',
    'setRowExpand',
    'toggleTreeExpand',
    'setTreeExpand',
    'clearRowExpand',
    'clearTreeExpand',

    // 状态清除方法
    'clearData',
    'clearSort',
    'clearFilter',
    'clearAll',
    'clearScroll',
    'clearSelected',
    'clearActived',
    'clearCellAreas',
    'clearCopyCellArea',

    // 滚动方法
    'scrollTo',
    'scrollToRow',
    'scrollToColumn',

    // 导入导出方法
    'exportData',
    'openExport',
    'importData',
    'openImport',
    'print',
    'openPrint',

    // 查找方法
    'openFind',
    'closeFind',
    'prevFind',
    'nextFind',

    // 代理相关方法
    'getProxyInfo',
    'commitProxy',

    // 更新方法
    'updateFooter',
    'updateStatus',
    'updateData',
    'recalculate',
    'refreshScroll',

    // 其他特殊方法
    'getComputeMaps',
    'getRowNode',
    'getColumnNode',
    'getData',
    'getTableColumn',

    // 基础方法
    'getProps',
    'getPropField',
    'setProps',
    'setPropField',
  ];

  // 创建完整的方法映射
  const allMethods: Record<string, any> = {};

  // 为所有方法创建代理
  vxeGridMethodNames.forEach((methodName) => {
    allMethods[methodName] = createMethodProxy(methodName);
  });

  // 合并所有table、grid、form方法，包括原有的方法和我们扩展的方法
  const methods = {
    // vxe-table原生方法代理
    ...allMethods,

    // 扩展方法
    ...extendedGridMethods,

    // 常用方法直接实现，优先使用
    getCheckboxRecords,
    setCheckboxRow,
    clearCheckboxRow,
    exportData,
    importData,
    print,
    validate,
    commitProxy,

    // 基础方法
    getProps: (prop: string) => unref(gridRef)?.getProps(prop),
    getPropField: (prop: string) => unref(gridRef)?.getPropField(prop),
    setProps: (props: Partial<VxeGridProps>) => unref(gridRef)?.setProps(props),
    setPropField: (prop: string, value: any) => unref(gridRef)?.setPropField(prop, value),
  };

  // @ts-ignore 忽略类型错误
  return [register, methods as VxeGridMethods<T>] as const;
}

// 导出类型
export type UseVxeGridReturnType = ReturnType<typeof useVxeGrid>;
